﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IEx.Utilities;
using log4net;

namespace IEx.Common
{
    public class Logger
    {
        #region Member variable
        private static readonly log4net.ILog logger = log4net.LogManager.GetLogger("Tools.IEx");

        private static StringBuilder errors = new StringBuilder();
        #endregion

        static Logger()
        {
            GlobalContext.Properties["date"] = DateTime.Now.ToString("yyyyMMdd");
            log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("LoggerConfig.xml"));
        }

        #region Public methods

        public static void Debug(string message)
        {
            //#if DEBUG
            //            System.Diagnostics.Debug.WriteLine(message);
            //#endif
            Console.WriteLine(message);
        }

        public static void Debug(string format, params object[] args)
        {
            //#if DEBUG
            //            System.Diagnostics.Debug.WriteLine(string.Format(format, args));
            //#endif
            Console.WriteLine(string.Format(format, args));
        }

        public static void WriteError(string message, Exception ex)
        {
            //Update date for Log file name.
            GlobalContext.Properties["date"] = DateTime.Now.ToString("yyyyMMdd");
            log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("LoggerConfig.xml"));

            string errorMsg = string.Format(string.Concat("{0} [DETAIL]: ({1}) [SOURCE]: {2}", Environment.NewLine, "******************************")
                , message, (ex != null ? ex.Message : ""), GetFriendlyErrorMessage(ex));

            Debug(errorMsg);
            logger.Error(errorMsg);
            errors.AppendLine(errorMsg);

            /*GlobalContext.Properties["date"] = DateTime.Now.ToString("yyyyMMdd");
            log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("LoggerConfig.xml"));

            logger.Error(errorMsg);
            DataFeedConfiguration Setting = DataFeedConfiguration.GetConfig();
            Utility.SendEmail(Setting.EmailSetting.ToEmailAddress, Setting.EmailSetting.Subject, errorMsg);*/
        }

        public static void SendErrorEmail()
        {
            if (errors.Length > 0)
            {
                EmailElement emailSetting = DataFeedConfiguration.GetConfig().EmailSetting;
                string error = errors.ToString();
                ClearLogger();

                try
                {
                    // Send email
                    Utility.SendEmail(emailSetting.ToEmailAddress, emailSetting.Subject, error);
                }
                catch (Exception ex)
                {
                    logger.Error("ERROR WHILE SENDING EMAIL: " + ex.Message);
                }
            }
        }

        public static void WriteLogInfo(string message)
        {
            Debug(message);

            //Update date for Log file name.
            GlobalContext.Properties["date"] = DateTime.Now.ToString("yyyyMMdd");
            log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("LoggerConfig.xml"));
            logger.Info(message);
        }

        public static string GetConfigValue(string configName, bool throwIfEmpty = true)
        {
            string value = ConfigurationManager.AppSettings[configName];
            if (throwIfEmpty && string.IsNullOrEmpty(value))
            {
                logger.Error(string.Format("\"{0}\" cannot be empty", configName), null);
                throw new ConfigurationErrorsException(string.Format("\"{0}\" cannot be empty", configName));
            }
            return value;
        }

        public static void ClearLogger()
        {
            errors.Clear();
        }
        #endregion

        #region Private methods
        private static string GetFriendlyErrorMessage(Exception ex)
        {
            if (ex == null)
                return "";
            string msg = "";
#if DEBUG
            StackTrace st = new StackTrace(ex, true);
            StackFrame[] frames = st.GetFrames();

            // Iterate over the frames extracting the information you need
            foreach (StackFrame frame in frames)
            {
                msg = string.Format("{0}:{1}({2},{3})", frame.GetFileName(), frame.GetMethod().Name, frame.GetFileLineNumber(), frame.GetFileColumnNumber());
                break;
            }

#else
            msg = ex.Source;
#endif

            return msg;
        }
        #endregion
    }
}
